﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TextToHTMLExtensionInterfaces;
using System.ComponentModel.Composition;
using System.Net;
using System.IO;
using System.Diagnostics;

namespace EPSConverterLibrary
{
    /// <summary>
    /// Plug-in that does the EPS rendering
    /// </summary>
    [Export(typeof(IRenderToHTML))]
    [ExportMetadata("type", typeof(Uri))]
    public class EPSRender : IRenderToHTML
    {
        /// <summary>
        /// Render only if it is an eps file!
        /// </summary>
        /// <param name="objToRender"></param>
        /// <returns></returns>
        public bool CanRender(object objToRender)
        {
            Uri u = objToRender as Uri;
            if (u == null)
                return false;

            string t = u.AbsolutePath;
            int dot = t.LastIndexOf(".");
            if (dot < 0)
                return false;
            t = t.Substring(dot + 1);
            return t == "eps";
        }

        /// <summary>
        /// Actually render this guy! Whoop!
        /// </summary>
        /// <param name="objToRender"></param>
        /// <returns></returns>
        public string Render(object objToRender)
        {
            Uri u = objToRender as Uri;

            string fname = u.AbsolutePath;
            int lastSlash = fname.LastIndexOf("/");
            if (lastSlash >= 0)
            {
                fname = fname.Substring(lastSlash + 1);
            }

            ///
            /// First step - download the eps file to our temp directory
            /// 

            WebRequest r = WebRequest.Create(u);
            WebResponse response = r.GetResponse();
            Stream output = response.GetResponseStream();

            FileInfo tempEPSFile = new FileInfo(Path.GetTempPath() + fname);
            using (Stream localFile = tempEPSFile.Create())
            {
                const int dataSize = 1024 * 8;
                byte[] data = new byte[dataSize];

                while (true)
                {
                    int bytesRead = output.Read(data, 0, dataSize);
                    if (bytesRead == 0)
                    {
                        break;
                    }
                    localFile.Write(data, 0, bytesRead);
                }
            }

            ///
            /// Now that the file is local, run the gs converter on it
            /// 

            FileInfo tempJPEGFile = new FileInfo(Path.ChangeExtension(tempEPSFile.FullName, ".jpg"));

            ProcessStartInfo sinfo = new ProcessStartInfo();
            sinfo.FileName = @"C:\Program Files\gs\gs8.63\bin\gswin32c.exe";
            sinfo.Arguments = "-sDEVICE=jpeg "
                + "-dJPEGQ=100 "
                + "-r120x120 "
                + "-sOutputFile=" + tempJPEGFile.Name + " "
                + "-dBATCH -dNOPAUSE "
                + tempEPSFile.Name;
            sinfo.CreateNoWindow = true;
            sinfo.RedirectStandardOutput = true;
            sinfo.UseShellExecute = false;
            sinfo.WorkingDirectory = tempEPSFile.DirectoryName;

            ///
            /// Now start the process. We switch the error mode
            /// so that when gs crashes it doesn't pop the dialog
            /// box. And because this is a process wide setting, we need
            /// to make sure two people don't try to start the process
            /// at once.
            /// 

            DateTime startime = DateTime.Now;
            Process gsproc = null;

            lock (this)
            {
                using (ChangeErrorMode newerr = new ChangeErrorMode(ChangeErrorMode.ErrorModes.FailCriticalErrors | ChangeErrorMode.ErrorModes.NoGpFaultErrorBox))
                {
                    gsproc = Process.Start(sinfo);
                    gsproc.PriorityClass = ProcessPriorityClass.Idle;
                }
            }

            ///
            /// Now monitor the i/o that comes back from there.
            /// 

            string error_seen = "";
            List<FileInfo> result = new List<FileInfo>();

            string line = "hi";
            while ((line = gsproc.StandardOutput.ReadLine()) != null)
            {
                line = line.Trim();
                if (line.StartsWith("Error:"))
                {
                    error_seen = line;
                }
            }

            ///
            /// Be good, wait for it to shut down - which should be seconds
            /// 

            gsproc.WaitForExit();
            return "<img src=\"" + tempJPEGFile.FullName + "\" />";
        }
    }
}
